package cn.airfei.netty.nio;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.*;
import java.util.Iterator;
import java.util.Set;

/**
 * @description:
 * @author: air
 * @create: 2021-01-14 13:58
 */
public class NIOServer {

    public static void main(String[] args) throws IOException {
        // 创建一个serverSocketChannel
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();

        Selector selector = Selector.open();

        // 绑定一个监听端口
        serverSocketChannel.socket().bind(new InetSocketAddress(8888));

        //　设置为非阻塞
        serverSocketChannel.configureBlocking(false);

        // 把serverSocketChannel注册到selector
        serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);


        // 循环等待客户端链接
        while (true){
            if (selector.select(1000)==0){
                System.out.println("服务器等待了1秒,没有连接");
                continue;
            }

            Set<SelectionKey> selectionKeys = selector.selectedKeys();

            Iterator<SelectionKey> keyIterator = selectionKeys.iterator();
            System.out.println("selector:"+selector.keys().size());

            while (keyIterator.hasNext()){
                SelectionKey selectionKey = keyIterator.next();
                if (selectionKey.isAcceptable()){
                    // 有新的客户端链接
                    // 分配一个socketChannel
                    SocketChannel socketChannel = serverSocketChannel.accept();
                    // 设置为非阻塞
                    socketChannel.configureBlocking(false);
                    // 将socketChannel注册到selector
                    socketChannel.register(selector,SelectionKey.OP_READ, ByteBuffer.allocate(1024));



                }else if (selectionKey.isReadable()){
                    // 通过key反向获取channel
                    SocketChannel channel = (SocketChannel) selectionKey.channel();
                    // 获取关联的buffer
                    ByteBuffer byteBuffer = (ByteBuffer) selectionKey.attachment();
                    channel.read(byteBuffer);
                    System.out.println("客户端发送的消息:"+new String(byteBuffer.array()));
                }

                // 手动删除集合中的selectionKey
                keyIterator.remove();

            }
        }
    }

}
